﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WFNetLib.Log;
using WFNetLib.TCP;
using WFNetLib.PacketProc;
using System.Net.Sockets;
using System.IO;
using WFNetLib;
using System.Security.Cryptography;
//using Vincent.WebConfigManager;

namespace GetData_TCPModbus
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }        
        string Screen1IP = "10.103.4.26";
        int Screen1No = 9;
        private bool m_bSendBusy = false;//此变量在数据更新中非常重要，请务必保留。
        private void Form1_Load(object sender, EventArgs e)
        {
            byte[] bb=new byte[4];
            bb[3]=0x42;
            bb[2]=0x70;
            bb[1]=0x00;
            bb[0]=0x00;          
            int f1=BitConverter.ToInt32(bb,0);
            TextLog.MaxUsage = 5000;
            LedDLL.InitDLLResource(this.Handle);
            ShowText("成功加载屏驱动",true);
            if (!PreProcLED())
            {
                MessageBox.Show("屏驱动操作出错，软件功能无法执行，请检查相关信息!!!!");
            }
            //Delta = 400;
            bAdjusted = false;
            toolStripButton1.Text = "停止定时采集";
            //timer1_Tick(null, null);
            timer1.Enabled = true;
        }
        bool PreProcLED()
        {
            int retry=20;
            try
            {
                while(retry!=0)
                {
                    retry--;
                    //添加屏幕
                    int result = LedDLL.AddScreen(LedDLL.CONTROLLER_TYPE_5M2, Screen1No, 320, 64, 2, 1,
                        0, 0, 0, 0, "", 0, Screen1IP, 5005,
                        "C:\\ScreenStatus.ini");
                    ShowText(LedDLL.GetErrorMessage("AddScreen", result));
                    if (result != 0)
                    {
                        if (result == LedDLL.RETURN_ERROR_RA_SCREENNO)//屏幕重复
                        {
                            //删除屏显
                            result = LedDLL.DeleteScreen(Screen1No);
                            ShowText(LedDLL.GetErrorMessage("DeleteScreen", result));
                            if (result != 0)
                                return false;
                            else
                                continue;
                        }
                    }
                    //添加节目
                    result = LedDLL.AddScreenProgram(Screen1No, 0, 0, 65535, 12, 3, 2011, 11, 26, 1, 1, 1, 1, 1, 1, 1, 8, 0, 18, 0);
                    ShowText(LedDLL.GetErrorMessage("AddScreenProgram", result));
                    if (result != 0)
                    {
                        continue;
                    }
                    result = LedDLL.AddScreenProgramBmpTextArea(Screen1No, 0, 0, 0, 320, 64);
                    ShowText(LedDLL.GetErrorMessage("AddScreenProgramBmpTextArea", result));
                    if (result != 0)
                    {
                        continue;
                    }
                    break;
                }
            }
            catch (System.Exception ex)
            {
                ShowText("屏驱动操作出错" + ex.Message);
                return false;
            }
            if (retry == 0)
            {
                ShowText("屏驱动操作出错");
                return false;
            }
            return true;
        }
        TcpModbusPacket ModbusWork(byte[] tx,TcpModbusPacket.FunctionCode type)
        {
            string str;
            TCPSyncClient tcp = new TCPSyncClient();
            tcp.TCPServerName = "10.103.4.106";
            tcp.SaveDataProcessCallback = new SaveDataProcessCallbackDelegate(TcpModbusPacket.SaveDataProcessCallbackProc);
            tcp.TCPServerPort = 502;
            //ShowText("-----------------------"+DateTime.Now.ToLocalTime()+"------------------------");
            if (!tcp.Conn())
            {
                str = "无法连接到服务器:";
                if (tcp.LastException.GetType() == typeof(SocketException))
                {
                    SocketException ex = (SocketException)tcp.LastException;
                    switch (ex.ErrorCode)
                    {
                        case 10061:
                            str += ex.Message;
                            break;
                        case 10060:
                            str += ex.Message;
                            break;
                    }
                }
                else
                    str = "未知错误:" + tcp.LastException.Message;
                ShowText(str);
                return null;
            }
            ShowText("发送数据:" + WFNetLib.Strings.StringsFunction.byteToHexStr(tx, " "));
            byte[] txBytes = TcpModbusPacket.MakePacket(0, 0, type, tx);
            if (!tcp.SendPacket(txBytes))
            {
                return null;
            }
            object o = tcp.ReceivePacket();
            if (o == null)
            {
                ShowText("未收到需要读取的数据");
                return null;
            }
            TcpModbusPacket tp = (TcpModbusPacket)o;
            ShowText("收到数据:" + WFNetLib.Strings.StringsFunction.byteToHexStr(tp.Data, " "));
            tcp.Close();
            return tp;
        }
        int Delta;
        bool bAdjusted;
        private void timer1_Tick(object sender, EventArgs e)
        {
            string str;
            try
            {
                if (VerifySoft())
                {
                    timer1.Enabled = false;
                    ShowText("定时周期到", true);
                    byte[] tx = new byte[4];
                    tx[0] = 0x00;//起始地址
                    tx[1] = 0xe9;
                    tx[2] = 0;//长度
                    tx[3] = 4;
                    TcpModbusPacket tp = ModbusWork(tx, TcpModbusPacket.FunctionCode.Read);
                    byte[] bb = new byte[4];
                    bb[3] = tp.Data[3];
                    bb[2] = tp.Data[4];
                    bb[1] = tp.Data[1];
                    bb[0] = tp.Data[2];
                    int f1 = BitConverter.ToInt32(bb, 0);
                    bb[3] = tp.Data[7];
                    bb[2] = tp.Data[8];
                    bb[1] = tp.Data[5];
                    bb[0] = tp.Data[6];
                    int f2 = BitConverter.ToInt32(bb, 0);
                    //                 if (DateTime.Now.Hour == 2)
                    //                 {
                    //                     if (!bAdjusted)
                    //                     {
                    //                         Delta = f1 - f2 - 20;
                    //                         bAdjusted = true;
                    //                     }
                    //                 }
                    //                 else
                    //                     bAdjusted = false;
                    int f3 = f1 - f2;// -Delta;
                    f3 = 120 - f3;
                    if (f3 < 0)
                        f3 = 0;
                    int result = LedDLL.DeleteScreenProgramAreaBmpTextFile(Screen1No, 0, 0, 0);
                    ShowText(LedDLL.GetErrorMessage("DeleteScreenProgramAreaBmpTextFile", result));
                    string file = System.Windows.Forms.Application.StartupPath + "\\CheWei.txt";
                    FileInfo f = new FileInfo(file);
                    // 如果文件所在的文件夹不存在则创建文件夹
                    if (!Directory.Exists(f.DirectoryName))
                        Directory.CreateDirectory(f.DirectoryName);
                    FileStream fs;
                    fs = new FileStream(file, FileMode.Create);
                    StreamWriter sw = new StreamWriter(fs);
                    str = string.Format("空闲车位: {0:D3}个", f3);
                    ShowText(str);
                    sw.Write(str);
                    //清空缓冲区
                    sw.Flush();
                    //关闭流
                    sw.Close();
                    fs.Close();/**/
                    //添加文件到图文区
                    result = LedDLL.AddScreenProgramAreaBmpTextFile(Screen1No, 0, 0, file, 1, "宋体", 32, 0, 1, 1, 2, 0);
                    ShowText(LedDLL.GetErrorMessage("AddScreenProgramAreaBmpTextFile", result));
                    if (result != 0)
                    {
                        if (PreProcLED())
                        {
                            result = LedDLL.AddScreenProgramAreaBmpTextFile(Screen1No, 0, 0, file, 1, "宋体", 32, 0, 1, 1, 2, 0);
                            ShowText(LedDLL.GetErrorMessage("AddScreenProgramAreaBmpTextFile", result));
                            if (result != 0)
                            {
                                ShowText("屏驱动操作出错，无法显示最新数据");
                                return;
                            }
                        }
                        else
                        {
                            ShowText("屏驱动操作出错，无法显示最新数据");
                            return;
                        }
                    }
                    int retry = 5;
                    result = 8;
                    while (retry != 0)
                    {
                        retry--;
                        if (result != 0)
                        {
                            result = LedDLL.SendScreenInfo(Screen1No, LedDLL.SEND_MODE_NET, LedDLL.SEND_CMD_SENDALLPROGRAM, 0);
                            ShowText(LedDLL.GetErrorMessage("SendScreenInfo", result));
                        }
                        else
                            break;
                    }
                }
            }
            catch (System.Exception ex)
            {
                ShowText("发生错误:"+ex.Message);
            }
            finally
            {
                timer1.Enabled = true; ;
            }
        }
        private delegate void ShowTextLog(string str, bool newSection);
        private void ShowTextLogProc(string str ,bool newSection)
        {
            if (textBox1.Text.Length > 20000)
                textBox1.Clear();
            if(newSection)
                textBox1.AppendText("---------------------" + DateTime.Now.ToString("yy年MM月dd日 hh:mm:ss") + "-------------------\r\n");
            textBox1.AppendText(str+"\r\n");
            TextLog.AddTextLog(str,newSection);
        }
        public void ShowText(string str, bool newSection)
        {
            this.Invoke(new ShowTextLog(ShowTextLogProc), str,newSection);
        }
        public void ShowText(string str)
        {
            this.Invoke(new ShowTextLog(ShowTextLogProc), str,false);
        }
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            if (toolStripButton1.Text == "开始定时采集")
            {
                toolStripButton1.Text = "停止定时采集";
                timer1.Enabled = true;
            }
            else
            {
                toolStripButton1.Text = "开始定时采集";
                timer1.Enabled = false;
            }
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            
            byte[] tx = new byte[200+5];
            tx[0] = 0x01;//起始地址
            tx[1] = 0x2c;
            tx[2] = 0;//长度
            tx[3] = 100;
            tx[4] = 200;//写入字节数
            for(int i=0;i<200;i++)
                tx[i+5] = (byte)i;
            //tx[6]=(byte)20;
            ModbusWork(tx, TcpModbusPacket.FunctionCode.Write);
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            byte[] tx = new byte[4];
            tx[0] = 0x00;//起始地址
            tx[1] = 0xe9;
            tx[2] = 0;//长度
            tx[3] = 4;
            TcpModbusPacket tp= ModbusWork(tx, TcpModbusPacket.FunctionCode.Read);
            byte[] bb = new byte[4];
            bb[3] = tp.Data[3];
            bb[2] = tp.Data[4];
            bb[1] = tp.Data[1];
            bb[0] = tp.Data[2];
            int f1 = BitConverter.ToInt32(bb, 0);
            bb[3] = tp.Data[7];
            bb[2] = tp.Data[8];
            bb[1] = tp.Data[5];
            bb[0] = tp.Data[6];
            int f2 = BitConverter.ToInt32(bb, 0);
            int f3 = f2 - f1;
        }
        bool VerifySoft()
        {
            const string VerifyVersion = "wfHXSJJK";
            SoftVerifyData svd;
            try
            {
                svd = SoftVerify.GetVerifyData(VerifyVersion);
            }
            catch (CryptographicException ex)//数据被更改
            {
                ShowText("系统关键数据被更改:" + ex.Message);
                return false;
            }
            if (svd.UsedDays > 60)
            {
                ShowText("系统关键数据1超限");
                return false;
            }
            else
            {
                DateTime cur = DateTime.Now;
                if (svd.CurTime.AddDays(1) < DateTime.Now || svd.CurTime > DateTime.Now)
                {
                    svd.UsedDays++;
                    svd.CurTime = DateTime.Now;
                }
            }
            if (svd.UsedTimes > 50000)
            {
                ShowText("系统关键数据2超限");
                return false;
            }
            else
            {
                svd.UsedTimes++;
            }
            SoftVerify.SetVerifyData(VerifyVersion, svd);
            return true;
        }
    }
}
